
import turtle as tu
import random as ra
import math

word = "Merry Christmas!" # 祝福语（要写的字）

tu.setup(1.0, 1.0, None, None)
tu.screensize(1.0, 1.0)    #设置画布大小
tu.bgcolor('black')  #设置画布颜色
tu.title("❄")
t = tu.Turtle()
t.screen.delay(0)
t.ht()               #隐藏画笔

class Hat():            #帽子类
    def __init__(self):   #初始化
        self.x=ra.randint(-1000,1000)      #帽子在画布中的x坐标位置
        self.y=ra.randint(500,1000)        #帽子在画布中的y坐标位置
        self.r=ra.uniform(0.5,1)
        self.k=ra.randint(-50,50)
        self.f = ra.uniform(-3.14, 3.14)
        self.speed = ra.randint(3, 8)

    def draw(self):
        t.penup()                  #提笔
        t.goto(self.x,self.y)      #设置帽子在画布中的初始坐标
        t.pendown()                #落笔
        t.seth(-20 + self.k)
        t.pensize(2)
        t.pencolor("white")
        t.begin_fill()
        t.fillcolor("white")
        t.fd(30 * self.r)
        t.circle(4 * self.r, 180)
        t.fd(30 * self.r)
        t.circle(4 * self.r, 180)
        t.end_fill()
        t.seth(75 + self.k)
        t.begin_fill()
        t.fillcolor("red")
        for i in range(5):
            t.fd(6 * self.r)
            t.right(20)
        t.seth(-10 + self.k)
        for i in range(5):
            t.fd(8 * self.r)
            t.right(15)
        t.seth(145 + self.k)
        for i in range(5):
            t.fd(5 * self.r)
            t.left(2)
        t.seth(90 + self.k)
        for i in range(5):
            t.fd(1 * self.r)
            t.left(2)
        t.seth(-90 + self.k)
        for i in range(4):
            t.fd(4 * self.r)
            t.right(6)
        t.seth(161 + self.k)
        t.fd(30 * self.r)
        t.end_fill()

    def change(self):
        if self.y >= -500:            #当帽子还在画布中时
            self.y -= self.speed     #设置上下移动速度
            self.x += self.speed * math.sin(self.f)    #设置左右移动速度
            self.f += 0.1            #可以理解成标志，改变左右移动的方向
        else:                        #当帽子漂出了画布时，重新生成一个袜子
            self.r = ra.uniform(0.5,1)
            self.x = ra.randint(-1000,1000)
            self.y = 500
            self.f = ra.uniform(-3.14,3.14)
            self.speed = ra.randint(3,8)
            self.k = ra.uniform(-50,50)



class Sock():            #袜子类
    def __init__(self):   #初始化
        self.x = ra.randint(-1000,1000)      #袜子在画布中的x坐标位置
        self.y = ra.randint(500,1000)                            #袜子在画布中的y坐标位置
        self.r = ra.uniform(0.5,1)
        self.s = ra.randint(-50,50)
        self.f = ra.uniform(-3.14, 3.14)
        self.speed = ra.randint(3, 8)

    def draw(self):
        t.penup()                  #提笔
        t.goto(self.x,self.y)      #设置袜子在画布中的初始坐标
        t.pendown()                #落笔
        t.seth(self.s)
        t.pensize(2)
        t.pencolor("white")
        t.begin_fill()
        t.fillcolor("white")
        t.fd(25 * self.r)
        t.circle(4 * self.r, 180)
        t.fd(25 * self.r)
        t.circle(4 * self.r, 180)
        t.end_fill()
        t.begin_fill()
        t.fillcolor("red")
        t.right(90)
        t.fd(20 * self.r)
        t.left(-100)
        t.fd(5 * self.r)
        t.circle(7 * self.r, 180)
        t.fd(15 * self.r)
        t.circle(5 * self.r, 90)
        t.fd(30 * self.r)
        t.end_fill()

    def change(self):
        if self.y >= -500:            #当袜子还在画布中时
            self.y -= self.speed     #设置上下移动速度
            self.x += self.speed * math.sin(self.f)    #设置左右移动速度
            self.f += 0.1            #可以理解成标志，改变左右移动的方向
        else:                        #当袜子漂出了画布时，重新生成一个袜子
            self.r = ra.uniform(0.5,1)
            self.x = ra.randint(-1000,1000)
            self.y = 500
            self.f = ra.uniform(-3.14,3.14)
            self.speed = ra.randint(3,8)

class Star():            #星星类
    def __init__(self):   #初始化
        self.r=1       #星星的初始大小
        self.x=ra.randint(-1000,1000)      #星星在画布中的x坐标位置
        self.y=ra.randint(-500,500)        #星星在画布中的y坐标位置
        self.c="gold"           #在星星的颜色列表中随机选择一个颜色
    def draw(self):                        #画星星的函数
        t.pensize(1)               #设置画笔大小
        t.penup()                  #提笔
        t.goto(self.x,self.y)      #设置星星在画布中的初始坐标
        t.pendown()                #落笔
        t.color(self.c)            #设置星星的外框颜色
        for i in range(5):         #循环画星星
            t.forward(self.r)
            t.right(144)
            t.forward(self.r)
            t.left(72)
    def change(self):              #改变星星的大小（星星不断增大）
        if self.r<=10:             #星星的最大大小不超过10
            self.r+=0.5          #递增
        else:                      #超过最大大小就重新画星星
            self.r = 1
            self.x = ra.randint(-1000, 1000)
            self.y = ra.randint(-500, 500)
            self.c = "gold"

class Snow():    #雪花类
    def __init__(self):
        self.r = ra.uniform(2,3)       #雪花的半径
        self.x = ra.randint(-1000,1000)   #雪花的横坐标
        self.y = ra.randint(500,1500)     #雪花的纵坐标
        self.f = ra.uniform(-3.14,3.14)   #雪花左右移动呈正弦函数
        self.speed = ra.randint(10,15)     #雪花移动速度
        self.color = "white"    #雪花的颜色
        self.outline = 2                #雪花的大小
    def draw(self):                #画每个雪花
        x=self.r                   #雪花的半径
        t.pensize(self.outline)    #雪花的大小
        t.penup()                  #提笔
        t.goto(self.x,self.y)      #随机位置
        t.pendown()                #落笔
        t.color(self.color)        #雪花颜色
        for i in range(6):        #循环画六个雪花瓣
            t.forward(x*5)
            t.backward(x*2)
            t.left(60)
            t.forward(x*2)
            t.backward(x*2)
            t.right(120)
            t.forward(x*2)
            t.backward(x*2)
            t.left(60)
            t.backward(x*3)
            t.right(60)
    def change(self):                    #雪花移动函数
        if self.y >= -500:            #当雪花还在画布中时
            self.y -= self.speed     #设置上下移动速度
            self.x -= self.speed * math.sin(self.f)    #设置左右移动速度
            self.f -= 0.1            #可以理解成标志，改变左右移动的方向
        else:                        #当雪花漂出了画布时，重新生成一个雪花
            self.r = ra.uniform(2,3)
            self.x = ra.randint(-1000,1000)
            self.y = 500
            self.f = ra.uniform(-3.14,3.14)
            self.speed = ra.randint(10,15)
            self.color = "white"
            self.outline = 2

Christmas=[]              #圣诞礼物列表
for i in range(66):           #循环增加圣诞礼物
    Christmas.append(Hat())   #圣诞帽
    Christmas.append(Sock())  #圣诞袜
    # Christmas.append(Star())  #星星
    Christmas.append(Snow())  #雪花
    Christmas.append(Snow())
while True:                   #开始画圣诞礼物
    tu.tracer(0)
    t.clear()
    t.penup()
    t.goto(-366,0)
    t.pendown()
    t.write(word, font=(
        "Comic Sans MS", 66, "bold"))  # 开始写字，"Merry Christmas!"为要写的字，"Comic Sans MS"为字体，66为字的大小，bold为粗体（可自行修改要写的字）

    for i in range(166):
        Christmas[i].draw()
        Christmas[i].change()
    tu.update()


tu.mainloop()